﻿using JshRCSWebApi.Infrastructure;
using JshRCSWebApi.Infrastructure.Domain.DTO.SysService;
using JshRCSWebApi.Infrastructure.Domain.VO.SysService;
using JshRCSWebApi.Service.SysService;
using JshRCSWebApi.SqlSugarDB.Model.jshrcs_initial;
using SqlSugar.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using ZstdSharp.Unsafe;

namespace JshRCSWebApi.ServiceImpl.SysService
{
    public class MenuServiceImpl : MenuService
    {
        private readonly Repository<dynamic> _repository;

        public MenuServiceImpl(Repository<dynamic> repository)
        {
            _repository = repository;
        }
        /// <summary>
        /// 获取菜单列表（树形）
        /// </summary>
        /// <param name="searchDTO"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> GetMenuList(MenuSearchDTO searchDTO)
        {
            int total = 0;
            var subMenuList = _repository.Context.Queryable<servicemenu>()
                                      .OrderBy(sm => sm.smSort)
                                      .ToPageList(searchDTO.pageNo, searchDTO.pageSize, ref total)
                                      .Select(sm => new MenuPageSearchDTO()
                                      {
                                         ID = sm.ID,
                                         smBriefIntroduction = sm.smBriefIntroduction,
                                         smParentID = sm.smParentID,
                                         smParentTitle = sm.smParentID == 0 ? "#" : _repository.Select<servicemenu>().Where(s => s.ID == sm.smParentID).First().smTitle,
                                         smPassed = sm.smPassed,
                                         smPath = sm.smPath,
                                         smName = sm.smName,
                                         smRedirect = sm.smRedirect,
                                         smTitle = sm.smTitle,
                                         smIcon = sm.smIcon,
                                         CreateTime = sm.CreateTime,
                                      }).ToList();
            var topLevelMunus = await GetMenuListByRecursion(subMenuList, 0);
            return await Task.Run(async () => ApiResult.Success("查询成功", new { menuList = topLevelMunus, total = total }));
        }
        public async Task<List<MenuPageSearchDTO>> GetMenuListByRecursion(List<MenuPageSearchDTO> subMenuList, long parentId)
        {
            var newlist = subMenuList.Where(D => D.smParentID == parentId).ToList();
            if (newlist.Count > 0)
            {
                newlist.ForEach(async d =>
                {
                    d.children = await GetMenuListByRecursion(subMenuList, d.ID); // 递归查询子菜单
                });
                return await Task.Run(async () => newlist);
            }
            return null;
        }

        /// <summary>
        /// 新增菜单
        /// </summary>
        /// <param name="addDTO"></param>
        /// <param name="UID"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> AddMenu(MenuAddDTO addDTO, int UID)
        {
            int menuId = 0;
            if (addDTO.smParentID == 0)  //父级菜单
            {
                int maxSort = _repository.SelectList<servicemenu>()
                                         .Where(sm => sm.smSort.Length == 2)
                                         .Select(sm => sm.smSort)
                                         .Select(s => int.Parse(s))
                                         .Max();
                 maxSort = maxSort == 0 ? 10 : ++maxSort;
                 menuId = _repository.AddReturnIdentity<servicemenu>(new servicemenu()
                        {
                            smBriefIntroduction = addDTO.smBriefIntroduction,
                            smComponent = addDTO.smComponent,
                            smIcon = addDTO.smIcon,
                            smIsLeaf = "N",
                            smName = addDTO.smName,
                            smParentID = addDTO.smParentID,
                            smPassed = addDTO.smPassed,
                            smPath = addDTO.smPath,
                            smRedirect = addDTO.smRedirect,
                            smSort = maxSort.ToString(),
                            smTitle = addDTO.smTitle,
                            CreateBy = UID,
                            CreateTime = DateTime.Now,
                        });
            }
            else//子菜单
            {
                var parentMenu =  _repository.Select<servicemenu>()
                                             .Where(m => m.smParentID == addDTO.smParentID)
                                             .First();
                int maxSort = 0;
                if (parentMenu!=null)
                {
                    maxSort = _repository.SelectList<servicemenu>()
                                          .Select(sm => sm.smSort)
                                          .Where(s => s.Length == 4)
                                          .Where(s => s.Substring(0, 2) == parentMenu.smSort.Substring(0, 2))
                                          .Select(s => int.Parse(s))
                                          .Max();
                }
                
                
                maxSort = maxSort == 0 ? 1000 : ++maxSort;
                

                menuId = _repository.AddReturnIdentity<servicemenu>(new servicemenu()
                        {
                            smBriefIntroduction = addDTO.smBriefIntroduction,
                            smComponent = addDTO.smComponent,
                            smIcon = addDTO.smIcon,
                            smIsLeaf = "Y",
                            smName = addDTO.smName,
                            smParentID = addDTO.smParentID,
                            smPassed = addDTO.smPassed,
                            smPath = addDTO.smPath,
                            smRedirect = addDTO.smRedirect,
                            smSort = maxSort.ToString(),
                            smTitle = addDTO.smTitle,
                            CreateBy = UID,
                            CreateTime = DateTime.Now,
                        });
            }
            RoleIdAndJurVO roleIdandJur =  _repository.Context.Queryable<serviceuser>()
                                                .LeftJoin<servicerole>((su, sr) => su.suSRID == sr.ID)
                                                .Where((su, sr) => su.ID == UID)
                                                .Select((su, sr) => new RoleIdAndJurVO {Id = sr.ID,sRJur = sr.srJurisdiction})
                                                .First();
            var adminRoleInfo = _repository.Select<servicerole>(sr => sr.ID == 1);
           if (!string.IsNullOrEmpty(roleIdandJur.sRJur)) 
            {
                roleIdandJur.sRJur += $",{menuId.ToString()}";
            }
            else
            {
                roleIdandJur.sRJur = menuId.ToString();
            }
            roleIdandJur.sRJur = string.IsNullOrEmpty(roleIdandJur.sRJur) ? menuId.ToString() : $"{roleIdandJur.sRJur},{menuId}";
            adminRoleInfo.srJurisdiction = string.IsNullOrEmpty(adminRoleInfo.srJurisdiction) ? menuId.ToString() : $"{adminRoleInfo.srJurisdiction},{menuId}";
            int countCommonRole = _repository.UpdateColumns(new servicerole()     
                                    {
                                        srJurisdiction = roleIdandJur.sRJur
                                    }, sr => sr.ID == roleIdandJur.Id, new string[] { "srJurisdiction" });
            int countAdminRole  = _repository.UpdateColumns(new servicerole()
                                    {
                                        srJurisdiction = adminRoleInfo.srJurisdiction
                                    }, s => s.ID == adminRoleInfo.ID, new string[] { "srJurisdiction" });
            return await Task.Run(() =>
            {
                return  countCommonRole > 0  && countAdminRole > 0 ? ApiResult.Success("新增菜单成功") : ApiResult.Error("新增菜单成功");
            });
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> DeleteMenu(int ID) 
        {
            var menuInfo = _repository.Select<servicemenu>()
                                         .Where(sm => sm.ID == ID)
                                         .First();
            if(menuInfo.ID == 1 || menuInfo.ID == 2 || menuInfo.ID == 3
                || menuInfo.ID == 4 || menuInfo.ID == 5)
            {
                return await Task.Run(async () => ApiResult.Error("系统管理或其子菜单不可删除"));
            }
             int count = 0; 
            if (menuInfo.smIsLeaf == "N") //删除根菜单（不影响菜单排序）
            {
               var menuList = _repository.SelectList<servicemenu>()
                                        .Where(sm => sm.smParentID == menuInfo.ID)
                                        .ToList();
               menuList.Add(menuInfo);
               count = _repository.Context.Deleteable<servicemenu>(menuList).ExecuteCommand();
            }
            else  //删除子菜单
            {
              count =  _repository.Delete<servicemenu>(menuInfo);
            }
            return await Task.Run(async () =>
            {
                return count > 0 ? ApiResult.Success("删除成功") : ApiResult.Error("删除失败");
            });
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="updateDTO"></param>
        /// <param name="v"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> UpdateMenu(MenuUpdateDTO updateDTO, int UID)
        {
            int count = _repository.UpdateColumns<servicemenu>(new servicemenu()
            {
                smBriefIntroduction = updateDTO.smBriefIntroduction,
                smComponent = updateDTO.smComponent,
                smIcon = updateDTO.smIcon,
                smName = updateDTO.smName,
                smParentID = updateDTO.smParentID,
                smPassed = updateDTO.smPassed,
                smPath = updateDTO.smPath,
                smSort = _repository.Select<servicemenu>().Where(sm => sm.ID == updateDTO.ID).First().smSort,
                smRedirect = updateDTO.smRedirect,
                smTitle = updateDTO.smTitle,
                ModifyTime = DateTime.Now,
                ModifyBy = UID
            },s => s.ID == updateDTO.ID,new string[]
            {
                "smBriefIntroduction","smComponent","smIcon","smName","smParentID","smPassed","smPath","smSort","smRedirect","smTitle","ModifyTime","ModifyBy"
            });
            return await Task.Run(() =>
            {
                return count > 0 ? ApiResult.Success("修改成功") : ApiResult.Error("修改失败");
            });
        }

        /// <summary>
        /// 获取权限的ID和标题（树形-用于菜单权限分配）
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> GetMenuIDAndTitleList()
        {
            var menuList = _repository.Context.Queryable<servicemenu>()
                                  .Where(sm => sm.smParentID == 0)
                                  .OrderBy(sm => sm.smSort)
                                  .Select(sm => new MenuSearchIDAndTitleVO()
                                  {
                                      ID = sm.ID,
                                      smTitle = sm.smTitle,
                                    
                                  }).ToList();
            if (menuList.Count > 0)
            {
                menuList.ForEach(item =>
                {
                    var subMenuList = _repository.SelectList<servicemenu>()
                                  .Where(sm => sm.smParentID == item.ID)
                                  .Select(sm => new MenuSearchIDAndTitleVO()
                                  {
                                      ID = sm.ID,
                                      smTitle = sm.smTitle
                                  }).ToList();
                    item.children = subMenuList;
                });
            }
            return await Task.Run(async () => ApiResult.Success("查询成功", menuList)) ;
        }

        /// <summary>
        /// 菜单上移
        /// </summary>
        /// <param name="iD"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> MoveUpMenu(int ID)
        {
          var menuInfo = _repository.Select<servicemenu>()
                                    .Where(sm => sm.ID == ID)
                                    .First();
            int count = 0;
            if (menuInfo.smIsLeaf == "Y") //子菜单上移
            {
              var upMenuInfo = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == menuInfo.smParentID && sm.ID != menuInfo.ID)
                                          .Where(sm => Convert.ToInt32(sm.smSort) < Convert.ToInt32(menuInfo.smSort))
                                          .OrderByDescending(sm => sm.smSort)
                                          .FirstOrDefault(); //选出选中菜单的上一级菜单
              if (upMenuInfo != null) //能找到上级菜单
              {
                 string upMenuSort = upMenuInfo.smSort;
                 upMenuInfo.smSort = menuInfo.smSort;
                 menuInfo.smSort = upMenuSort;
                 count = _repository.Update(menuInfo) + _repository.Update(upMenuInfo); //更新
               }
              else // 找不到上级菜单
              {
                    return await Task.Run(async () => ApiResult.Error("找不到上级菜单"));
              }
            }
            else //父菜单上移
            {
                //父级菜单
                var upMenuInfo = _repository.SelectWhereList<servicemenu>(sm => sm.smIsLeaf == "N" && sm.ID != menuInfo.ID)
                                        .Where(sm => Convert.ToInt32(sm.smSort) < Convert.ToInt32(menuInfo.smSort))
                                        .OrderByDescending(sm => sm.smSort)
                                        .FirstOrDefault(); //选出选中菜单的上一级菜单
                var upSubMenuList = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == upMenuInfo.ID);

                var currentSubMenuList = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == menuInfo.ID);
                if(upMenuInfo != null)  
                {
                    string currentSort = menuInfo.smSort;
                    string upSort = upMenuInfo.smSort;
                    menuInfo.smSort = upSort; 
                    upMenuInfo.smSort = currentSort;
                    upSubMenuList.ForEach(item =>
                    {
                        string sortStr = item.smSort;
                        item.smSort = currentSort + sortStr.Substring(2);
                    });
                    currentSubMenuList.ForEach(item =>
                    {
                        string sortStr = item.smSort;
                        item.smSort = upSort + sortStr.Substring(2);
                    });
                    upSubMenuList.Add(upMenuInfo);
                    currentSubMenuList.Add(menuInfo);
                    count = _repository.Update(upSubMenuList) + _repository.Update(currentSubMenuList);
                }
                else
                {
                    return await Task.Run(async () => ApiResult.Error("找不到上级菜单"));
                }
            }
            return await Task.Run(async () =>
            {
                return count > 0 ? ApiResult.Success("上移成功") : ApiResult.Error("上移失败");
            });
        }

        /// <summary>
        /// 菜单下移
        /// </summary>
        /// <param name="iD"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> MoveDownMenu(int ID)
        {
            var menuInfo = _repository.Select<servicemenu>()
                             .Where(sm => sm.ID == ID)
                             .First();
            int count = 0;
            if (menuInfo.smIsLeaf == "Y") // 子菜单下移
            {
                var downMenuInfo = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == menuInfo.smParentID && sm.ID != menuInfo.ID)
                                              .Where(sm => Convert.ToInt32(sm.smSort) > Convert.ToInt32(menuInfo.smSort))
                                              .OrderBy(sm => sm.smSort)
                                              .FirstOrDefault(); // 选出选中菜单的下一级菜单
                if (downMenuInfo != null) // 能找到下级菜单
                {
                    string downMenuSort = downMenuInfo.smSort;
                    downMenuInfo.smSort = menuInfo.smSort;
                    menuInfo.smSort = downMenuSort;
                    count = _repository.Update(menuInfo) + _repository.Update(downMenuInfo); // 更新
                }
                else // 找不到下级菜单
                {
                    return await Task.Run(() => ApiResult.Error("找不到下级菜单"));
                }
            }
            else // 父菜单下移
            {
                // 父级菜单
                var downMenuInfo = _repository.SelectWhereList<servicemenu>(sm => sm.smIsLeaf == "N" && sm.ID != menuInfo.ID)
                                              .Where(sm => Convert.ToInt32(sm.smSort) > Convert.ToInt32(menuInfo.smSort))
                                              .OrderBy(sm => sm.smSort)
                                              .FirstOrDefault(); // 选出选中菜单的下一级菜单
                var downSubMenuList = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == downMenuInfo.ID);

                var currentSubMenuList = _repository.SelectWhereList<servicemenu>(sm => sm.smParentID == menuInfo.ID);
                if (downMenuInfo != null)
                {
                    string currentSort = menuInfo.smSort;
                    string downSort = downMenuInfo.smSort;
                    menuInfo.smSort = downSort;
                    downMenuInfo.smSort = currentSort;
                    downSubMenuList.ForEach(item =>
                    {
                        string sortStr = item.smSort;
                        item.smSort = currentSort + sortStr.Substring(2);
                    });
                    currentSubMenuList.ForEach(item =>
                    {
                        string sortStr = item.smSort;
                        item.smSort = downSort + sortStr.Substring(2);
                    });
                    downSubMenuList.Add(downMenuInfo);
                    currentSubMenuList.Add(menuInfo);
                    count = _repository.Update(downSubMenuList) + _repository.Update(currentSubMenuList);
                }
                else
                {
                    return await Task.Run(() => ApiResult.Error("找不到下级菜单"));
                }
            }
            return await Task.Run(() =>
            {
                return count > 0 ? ApiResult.Success("下移成功") : ApiResult.Error("下移失败");
            });
        }

        /// <summary>
        /// 获取所有父菜单
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> GetParentsMenus()
        {
          var parentMenus = _repository.SelectList<servicemenu>()
                                       .Where(s => s.smParentID == 0)
                                       .Select(s => new { ID = s.ID, smTitle = s.smTitle,smPath = s.smPath })
                                       .ToList();
          return await Task.Run(async () => ApiResult.Success("查询成功",parentMenus) );
        }

        /// <summary>
        /// 根据ID获取菜单集合
        /// </summary>
        /// <param name="iD"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<ApiResult> GetMenuListByID(int ID)
        {
            if(ID == 0)
            {
                var parentMenus = _repository.SelectList<servicemenu>()
                                             .Where(s => s.smParentID == 0)
                                             .Select(s => new { ID = s.ID, smTitle = s.smTitle, smPath = s.smPath })
                                             .ToList();
                return await Task.Run(async () =>ApiResult.Success("查询成功", parentMenus));
            }
            else
            {
                var parentMenu = _repository.Select<servicemenu>(s => s.ID == ID);
                var childrenMenus = _repository.SelectList<servicemenu>()
                                               .Where(s => s.smParentID == ID)
                                               .Select(s => new { ID = s.ID, smTitle = s.smTitle, smPath = s.smPath })
                                               .ToList();
                return await Task.Run(async () =>
                    ApiResult.Success("查询成功", new { ID = parentMenu.ID, smTitle = parentMenu.smTitle, children = childrenMenus }));
            }
        }
    }
}
